package com.mall.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.mall.common.Const;
import com.mall.common.ServerResponse;
import com.mall.dao.*;
import com.mall.pojo.*;
import com.mall.service.IOrderService;
import com.mall.util.BigDecimalUtil;
import com.mall.util.DateTimeUtil;
import com.mall.util.PropertiesUtil;
import com.mall.vo.OrderItemVo;
import com.mall.vo.OrderProductVo;
import com.mall.vo.OrderVo;
import com.mall.vo.ShippingVo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * Created by xiaoyao on 2017/8/31.
 */
@Service("iOrderService")
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ShippingMapper shippingMapper;

    /**
     * 生成订单
     * @param userId
     * @param shippingId
     * @return
     */
    //封装OrderVo，用于返回给前端
    private OrderVo assembleOrderVo(Order order,List<OrderItem> orderItemList){
        OrderVo orderVo = new OrderVo();
        orderVo.setOrderNo(order.getOrderNo());
        orderVo.setPayment(order.getPayment());
        orderVo.setPaymentType(order.getPaymentType());
        orderVo.setPaymentTypeDesc(Const.PaymentTypeEnum.codeOf(order.getPaymentType()).getValue());

        orderVo.setPostage(order.getPostage());
        orderVo.setStatus(order.getStatus());
        orderVo.setStatusDesc(Const.OrderStatusEnum.codeOf(order.getStatus()).getValue());

        orderVo.setShippingId(order.getShippingId());
        Shipping shipping = shippingMapper.selectByPrimaryKey(order.getShippingId());
        if(shipping != null){
            orderVo.setReceiverName(shipping.getReceiverName());
            orderVo.setShippingVo(assembleShippingVo(shipping));
        }

        orderVo.setPaymentTime(DateTimeUtil.dateToStr(order.getPaymentTime()));
        orderVo.setSendTime(DateTimeUtil.dateToStr(order.getSendTime()));
        orderVo.setCreateTime(DateTimeUtil.dateToStr(order.getCreateTime()));
        orderVo.setCloseTime(DateTimeUtil.dateToStr(order.getCloseTime()));
        orderVo.setEndTime(DateTimeUtil.dateToStr(order.getEndTime()));

        orderVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));

        List<OrderItemVo> orderItemVoList = Lists.newArrayList();
        for(OrderItem orderItem : orderItemList){
            OrderItemVo orderItemVo = assembleOrderItemVo(orderItem);
            orderItemVoList.add(orderItemVo);
        }
        orderVo.setOrderItemVoList(orderItemVoList);
        return orderVo;
    }

    //封装OrderItemVo
    private OrderItemVo assembleOrderItemVo(OrderItem orderItem){
        OrderItemVo orderItemVo = new OrderItemVo();
        orderItemVo.setOrderNo(orderItem.getOrderNo());
        orderItemVo.setProductId(orderItem.getProductId());
        orderItemVo.setProductName(orderItem.getProductName());
        orderItemVo.setQuantity(orderItem.getQuantity());
        orderItemVo.setCurrentUnitPrice(orderItem.getCurrentUnitPrice());
        orderItemVo.setTotalPrice(orderItem.getTotalPrice());
        orderItemVo.setCreateTime(DateTimeUtil.dateToStr(orderItem.getCreateTime()));
        orderItemVo.setProductImage(orderItem.getProductImage());
        return orderItemVo;
    }

    //封装ShippingVo
    private ShippingVo assembleShippingVo(Shipping shipping){
        ShippingVo shippingVo = new ShippingVo();
        shippingVo.setReceiverName(shipping.getReceiverName());
        shippingVo.setReceiverAddress(shipping.getReceiverAddress());
        shippingVo.setReceiverCity(shipping.getReceiverCity());
        shippingVo.setReceiverMobile(shipping.getReceiverMobile());
        shippingVo.setReceiverPhone(shipping.getReceiverPhone());
        shippingVo.setReceiverDistrict(shipping.getReceiverDistrict());
        shippingVo.setReceiverProvince(shipping.getReceiverProvince());
        shippingVo.setReceiverZip(shipping.getReceiverZip());
        return shippingVo;
    }

    //封装清空购物车中已购商品的方法；
    private void cleanOrderCart(List<Cart> cartList){
        for(Cart cart : cartList){
            cartMapper.deleteByPrimaryKey(cart.getId());
        }
    }
    //封装减少库存的方法；
    private void reduceProductStock(List<OrderItem> orderItemList){
        for(OrderItem orderItem : orderItemList){
            Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
            product.setStock(product.getStock()-orderItem.getQuantity());
            productMapper.updateByPrimaryKeySelective(product);
        }
    }
    //组装订单的封装,如果返回空则没有封装成功；
    private Order assembleOrder(Integer userId,Integer shippingId,BigDecimal payment){
        Order order = new Order();
        order.setStatus(Const.OrderStatusEnum.NO_PAY.getCode());  //订单状态
        order.setUserId(userId);
        order.setShippingId(shippingId);
        order.setPostage(0);    //运费，暂都为零，包邮；
        order.setPaymentType(Const.PaymentTypeEnum.ONLINE_PAY.getCode());  //支付方式
        order.setPayment(payment);   //订单金额
        //组装订单号
        long orderNo = this.generateOrderNo();
        order.setOrderNo(orderNo);
        int rowCount = orderMapper.insert(order);
        if(rowCount > 0){
            return order;
        }
        return null;
    }
    //封装订单号生成的方法,这里只是利用时间戳，简单的处理得到订单后，后面根据业务要求再优化设计；
    private long generateOrderNo(){
        long currentTime = System.currentTimeMillis();
        return currentTime+new Random().nextInt(100);
    }
    //封装计算订单总价的方法(遍历相加)；
    private BigDecimal getOrderTotalPrice(List<OrderItem> orderItemList){
        BigDecimal payment = new BigDecimal("0");
        for(OrderItem orderItem : orderItemList){
            payment = BigDecimalUtil.add(payment.doubleValue(),orderItem.getTotalPrice().doubleValue());
        }
        return payment;
    }
    //封装子订单明细的逻辑处理；
    private ServerResponse<List<OrderItem>> getCartOrderItem(Integer userId,List<Cart> cartList){
        //new一个OrderItem的list，供下面通过foreach循环装载item,并返回；
        List<OrderItem> orderItemList = Lists.newArrayList();
        if(CollectionUtils.isEmpty(cartList)){
            return ServerResponse.createByErrorMessage("购物车中没有选中商品！");
        }
        //遍历校验选中商品（在售状态，库存），校验通过后数据插入到数据库订单表当中；
        for(Cart cartItem : cartList){
            //new一个OrderItem对象，供下面封装使用；
            OrderItem orderItem = new OrderItem();
            //Product对象存储根据遍历的id获取的Product对象
            Product product = productMapper.selectByPrimaryKey(cartItem.getProductId());
            //校验在售状态
            if(Const.ProductStatusEnum.ON_SALE.getCode() != product.getStatus()){
                return ServerResponse.createByErrorMessage("产品"+product.getName()+"不是在线售卖状态");
            }
            //校验库存
            if(product.getStock() < cartItem.getQuantity()){
                return ServerResponse.createByErrorMessage("产品"+product.getName()+"超出库存");
            }
            //组装选中商品进入订单列表；
            orderItem.setUserId(userId);
            orderItem.setProductId(product.getId());
            orderItem.setProductName(product.getName());
            orderItem.setProductImage(product.getMainImage());
            orderItem.setQuantity(cartItem.getQuantity());
            orderItem.setCurrentUnitPrice(product.getPrice());
            orderItem.setTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(),cartItem.getQuantity().doubleValue()));
            orderItemList.add(orderItem);
        }
        return ServerResponse.createBySuccess(orderItemList);
    }

    /**
     * 生成订单，多个参数
     * @param userId
     * @param shippingId
     * @param
     * @param orderPrice
     * @return
     */
    public ServerResponse createParamOrder(Integer userId,Integer shippingId,String cartIds,BigDecimal orderPrice){
        //遍历并处理cartid，获取商品列表
        String[] cartIdArr =  cartIds.split(",");
        List<Cart> cartList =  Lists.newArrayList();
        for (String id : cartIdArr) {
            Integer cartId =  Integer.parseInt(id);
            Cart orderItem = cartMapper.selectByPrimaryKey(cartId);
            cartList.add(orderItem);
        }
        //调用封装的方法生成并得到订单详情，前端传递商品列表
        ServerResponse<List<OrderItem>> serverResponse = this.getCartOrderItem(userId,cartList);
        if(!serverResponse.isSuccess()){
            return serverResponse;
        }
        List<OrderItem> orderItemList = serverResponse.getData();
        //订单总价
        BigDecimal payment = orderPrice;
        //生成订单
        Order order = this.assembleOrder(userId,shippingId,payment);
        if(order == null){
            return ServerResponse.createByErrorMessage("生成订单错误");
        }
        if(CollectionUtils.isEmpty(orderItemList)){
            return ServerResponse.createByErrorMessage("订单商品为空");
        }
        for(OrderItem orderItem : orderItemList){//给详细订单传入订单号
            orderItem.setOrderNo(order.getOrderNo());
        }
        //mybatis批量插入
        orderItemMapper.batchInsert(orderItemList);
        //订单生成成功，减少库存
        this.reduceProductStock(orderItemList);
        //清空购物车中的已购商品；
        this.cleanOrderCart(cartList);
        //返回给前端数据
        OrderVo orderVo = assembleOrderVo(order,orderItemList);
        return ServerResponse.createBySuccess(orderVo);
    }
    // 新增订单的方法
    public ServerResponse createOrder(Integer userId,Integer shippingId){
        //获取购物车选中商品
        List<Cart> cartList = cartMapper.selectCheckedCartByUserId(userId);
        //计算订单总价（调用封装的子订单明细生成并获取子订单，计算总价）
        ServerResponse<List<OrderItem>> serverResponse = this.getCartOrderItem(userId,cartList);
        if(!serverResponse.isSuccess()){
            return serverResponse;
        }
        List<OrderItem> orderItemList = serverResponse.getData();
        BigDecimal payment = this.getOrderTotalPrice(orderItemList);
        //生成订单
        Order order = this.assembleOrder(userId,shippingId,payment);
        if(order == null){
            return ServerResponse.createByErrorMessage("生成订单错误");
        }
        if(CollectionUtils.isEmpty(orderItemList)){
            return ServerResponse.createByErrorMessage("订单商品为空");
        }
        for(OrderItem orderItem : orderItemList){//给详细订单传入订单号
            orderItem.setOrderNo(order.getOrderNo());
        }
        //mybatis批量插入
        orderItemMapper.batchInsert(orderItemList);
        //订单生成成功，减少库存
        this.reduceProductStock(orderItemList);
        //清空购物车中的已购商品；
        this.cleanOrderCart(cartList);
        //返回给前端数据
        OrderVo orderVo = assembleOrderVo(order,orderItemList);
        return ServerResponse.createBySuccess(orderVo);
    }
    /**
     * 取消订单
     * @param userId
     * @param orderNo
     * @return
     */
    public ServerResponse<String> cancelOrder(Integer userId,Long orderNo){
        //校验传入的订单号
        Order order = orderMapper.selectByUserIdOrderNo(userId,orderNo);
        if(order == null){
            return ServerResponse.createByErrorMessage("订单号错误，未查询到");
        }
        //已付款订单无法取消
        if(order.getStatus() == Const.OrderStatusEnum.PAID.getCode()){
            return ServerResponse.createByErrorMessage("订单已支付，无法取消");
        }
        //通过上面校验，即可修改订单状态为取消状态；
        Order updateOrder = new Order();
        updateOrder.setId(order.getId());
        updateOrder.setStatus(Const.OrderStatusEnum.CANCELED.getCode());
        int row = orderMapper.updateByPrimaryKeySelective(updateOrder);
        //校验数据库是否发生改变
        if(row > 0){
            return ServerResponse.createBySuccessMessage("取消订单成功");
        }
        //给前端返回响应值
        return ServerResponse.createByErrorMessage("取消订单失败");
    }

    /**
     * 获取购物车中已选商品的订单视图
     * @param userId
     * @return
     */
    public ServerResponse<OrderProductVo> getCartCheckedProductOrder(Integer userId){
        OrderProductVo orderProductVo = new OrderProductVo();
        //获取OrderItemVo（需要OrderItem） 和 productTotalPrice 填充OrderProductVo
        //获取OrderItem
        List<Cart> cartList = cartMapper.selectCheckedCartByUserId(userId);
        ServerResponse serverResponse = this.getCartOrderItem(userId,cartList);
        if(!serverResponse.isSuccess()){
            return serverResponse;
        }
        List<OrderItem> orderItemList = (List<OrderItem>)serverResponse.getData();
        List<OrderItemVo> orderItemVoList = Lists.newArrayList();
        BigDecimal payment = new BigDecimal("0");
        for(OrderItem orderItem : orderItemList){
            payment = BigDecimalUtil.add(payment.doubleValue(),orderItem.getTotalPrice().doubleValue());
            orderItemVoList.add(assembleOrderItemVo(orderItem));
        }
        orderProductVo.setOrderItemVoList(orderItemVoList);
        orderProductVo.setProductTotalPrice(payment);
        orderProductVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));
        return ServerResponse.createBySuccess(orderProductVo);
    }


    /**
     * 获取订单详情
     * @param userId
     * @param orderNo
     * @return
     */
    public ServerResponse getdetail(Integer userId,long orderNo){
        //通过用户名和订单号获取订单
        Order order = orderMapper.selectByUserIdOrderNo(userId,orderNo);
        if(order == null){
            return ServerResponse.createByErrorMessage("没有该用户的订单信息");
        }
        List<OrderItem> orderItemList = orderItemMapper.getByUserIdOrderNo(userId,orderNo);
        OrderVo orderVo = assembleOrderVo(order,orderItemList);
        return ServerResponse.createBySuccess(orderVo);
    }
    /**
     * 订单列表
     * @param userId
     * @param pageNum
     * @param pageSize
     * @return
     */
    public ServerResponse getlist(Integer userId,Integer pageNum, Integer pageSize){
        //分页处理
        PageHelper.startPage(pageNum,pageSize);
        //根据userId获取orderList
        List<Order> orderList = orderMapper.selectByUserId(userId);
        //由orderList和userId获得orderVoList
        List<OrderVo> orderVoList = assembleOrderVoList(userId,orderList);
        PageInfo pageInfo = new PageInfo(orderList);
        pageInfo.setList(orderVoList);
        return ServerResponse.createBySuccess(pageInfo);
    }

    //封装orderVoList
    private List<OrderVo> assembleOrderVoList(Integer userId,List<Order> orderList){
        List<OrderVo> orderVoList = Lists.newArrayList();
        for(Order order : orderList){
            List<OrderItem> orderItemList = Lists.newArrayList();
            if(userId == null){
                //管理员查询时不需要传userId
                orderItemList = orderItemMapper.getByOrderNo(order.getOrderNo());
            }else {
                orderItemList = orderItemMapper.getByUserIdOrderNo(userId,order.getOrderNo());
            }
            OrderVo orderVo = assembleOrderVo(order,orderItemList);
            orderVoList.add(orderVo);
        }
        return orderVoList;
    }


    /**
     * 管理端获得订单详情
     * @param orderNo
     * @return
     */
    public ServerResponse manageDetail(long orderNo){
        //通过用户名和订单号获取订单
        Order order = orderMapper.selectByOrderNo(orderNo);
        if(order == null){
            return ServerResponse.createByErrorMessage("没有该用户的订单信息");
        }
        List<OrderItem> orderItemList = orderItemMapper.getByOrderNo(orderNo);
        OrderVo orderVo = assembleOrderVo(order,orderItemList);
        return ServerResponse.createBySuccess(orderVo);
    }

    /**
     * 管理员获取订单列表
     * @param pageNum
     * @param pageSize
     * @return
     */
    public ServerResponse manageList(Integer pageNum, Integer pageSize){
        //分页处理
        PageHelper.startPage(pageNum,pageSize);
        //根据userId获取orderList
        List<Order> orderList = orderMapper.selectAllOrder();
        //由orderList和userId获得orderVoList
        List<OrderVo> orderVoList = assembleOrderVoList(null,orderList);
        PageInfo pageInfo = new PageInfo(orderList);
        pageInfo.setList(orderVoList);
        return ServerResponse.createBySuccess(pageInfo);
    }

    /**
     * 管理员根据订单号查询订单
     * @param orderNo
     * @param pageNum
     * @param pageSize
     * @return
     */
    public ServerResponse manageSearch(long orderNo,Integer pageNum, Integer pageSize){
        //分页处理
        PageHelper.startPage(pageNum,pageSize);
        //根据userId获取orderList
        Order order = orderMapper.selectByOrderNo(orderNo);
        if(order == null){
            return ServerResponse.createByErrorMessage("没有该订单信息");
        }
        List<OrderItem> orderItemList = orderItemMapper.getByOrderNo(orderNo);
        OrderVo orderVo = assembleOrderVo(order,orderItemList);
        //由orderList和userId获得orderVoList
        PageInfo pageInfo = new PageInfo(Lists.newArrayList(order));
        pageInfo.setList(Lists.newArrayList(orderVo));
        return ServerResponse.createBySuccess(pageInfo);
    }

    /**
     * 管理员的发货处理
     * @return
     */
    public  ServerResponse<String> manageSendGoods(Long ordereNo){
        Order order = orderMapper.selectByOrderNo(ordereNo);
        if(order != null){
            if(order.getStatus() == Const.OrderStatusEnum.PAID.getCode()){
                order.setStatus(Const.OrderStatusEnum.SHIPPED.getCode());
                order.setSendTime(new Date());
                orderMapper.updateByPrimaryKeySelective(order);
                return ServerResponse.createBySuccessMessage("发货成功");
            }
        }
        return ServerResponse.createByErrorMessage("订单错误，不能发货");
    }


}
